package com.xuanwei.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.xuanwei.core.entity.vo.CartVo;
import com.xuanwei.core.exception.XwException;
import com.xuanwei.core.service.IXwCartService;
import com.xuanwei.dao.entity.*;
import com.xuanwei.dao.mapper.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author mjy
 * @since 2019-07-08
 */
@Service
public class XwCartServiceImpl extends ServiceImpl<XwCartMapper, XwCart> implements IXwCartService {

    private XwProductSkuMapper productSkuMapper;

    private XwProductMapper productMapper;

    private XwProductAttributeValueMapper productAttributeValueMapper;

    private XwProductAttributeMapper productAttributeMapper;


    public XwCartServiceImpl(XwProductSkuMapper productSkuMapper,
                             XwProductMapper productMapper,
                             XwProductAttributeValueMapper productAttributeValueMapper,
                             XwProductAttributeMapper productAttributeMapper) {
        this.productSkuMapper = productSkuMapper;
        this.productMapper = productMapper;
        this.productAttributeValueMapper = productAttributeValueMapper;
        this.productAttributeMapper = productAttributeMapper;
    }

    @Override
    public void add(Integer skuId, Integer count, Integer userId) {

        //无需锁,单人操作
        XwCart xwCart = baseMapper.selectOne(new QueryWrapper<XwCart>().select("id,`count`")
                .eq("sku_id", skuId).eq("user_id", userId));
        //没有添加过商品
        if (xwCart == null) {
            XwCart cart = generateCart(skuId, count);
            cart.setUserId(userId);
            save(cart);
        } else {
            Integer _count = xwCart.getCount();
            xwCart.setCount(_count + count);
            xwCart.setUpdateTime(LocalDateTime.now());
            updateById(xwCart);
        }

    }

    public XwCart generateCart(Integer skuId, Integer count) {

        XwCart cart = new XwCart();
        //悲观锁库存
        XwProductSku productSku = productSkuMapper.selectOne(new QueryWrapper<XwProductSku>()
                .select("id,product_id,attribute_ids,stock,price")
                .eq("id", skuId)
                .eq("`status`", 0).last("for update"));
        if (productSku == null) {
            throw new XwException("商品不存在");
        }
        if (count > productSku.getStock()) {
            throw new XwException("商品库存不足");
        }
        XwProduct product = productMapper.selectOne(new QueryWrapper<XwProduct>()
                .select("id,`name`,main_image")
                .eq("id", productSku.getProductId())
                .eq("`status`", 0));

        cart.setProductId(product.getId());
        cart.setProductName(product.getName());
        cart.setProductImage(product.getMainImage());
        cart.setPrice(productSku.getPrice());
        cart.setSkuId(productSku.getId());
        cart.setCreateTime(LocalDateTime.now());
        cart.setUpdateTime(LocalDateTime.now());
        cart.setCount(count);

        String attributeIds = productSku.getAttributeIds();
        List<Integer> ids = Arrays.stream(attributeIds.split("-")).map(Integer::parseInt).collect(Collectors.toList());
        StringBuffer stringBuffer = new StringBuffer();
        ids.forEach(s -> {
            XwProductAttributeValue productAttributeValue = productAttributeValueMapper.selectOne(
                    new QueryWrapper<XwProductAttributeValue>()
                            .select("id,product_attribute_id,`value`,image_url")
                            .eq("id", s));

            XwProductAttribute productAttribute = productAttributeMapper.selectOne(
                    new QueryWrapper<XwProductAttribute>()
                            .select("id,`name`")
                            .eq("id", productAttributeValue.getProductAttributeId()));

            if (StringUtils.isNotBlank(productAttributeValue.getImageUrl())) {
                cart.setProductImage(productAttributeValue.getImageUrl());
            }
            String name = productAttribute.getName();
            String value = productAttributeValue.getValue();
            stringBuffer.append(name).append(":").append(value).append(";");
        });
        cart.setProductAttributeName(stringBuffer.toString());

        return cart;
    }

    @Override
    public void updateCount(Integer cartId, Integer count) {
        //无需锁,单人操作
        XwCart xwCart = baseMapper.selectOne(new QueryWrapper<XwCart>().select("id")
                .eq("id", cartId));
        if (xwCart == null) {
            throw new XwException("购物车不存在");
        }
        xwCart.setCount(count);
        xwCart.setUpdateTime(LocalDateTime.now());
        updateById(xwCart);
    }

    @Override
    public List<CartVo> cartList(Integer userId) {

        List<XwCart> carts = baseMapper.selectList(new QueryWrapper<XwCart>()
                .select("id,product_image,product_name,product_attribute_name,`count`,price")
                .eq("user_id", userId).orderByDesc("create_time"));

        List<CartVo> cartVos = Lists.newArrayListWithCapacity(carts.size());
        carts.forEach(s -> {
            CartVo cartVo = new CartVo();
            cartVo.setId(s.getId());
            cartVo.setProductName(s.getProductName());
            cartVo.setSkuName(s.getProductAttributeName());
            cartVo.setCount(s.getCount());
            cartVo.setPrice(s.getPrice());
            cartVo.setImage(s.getProductImage());
            cartVos.add(cartVo);
        });
        return cartVos;
    }

    @Override
    public void deleteCart(List<Integer> ids) {
        baseMapper.deleteBatchIds(ids);
    }

    @Override
    public Integer allCount(Integer userId) {
        List<XwCart> carts = list(new QueryWrapper<XwCart>()
                .select("id,`count`")
                .eq("user_id", userId));

        return carts.stream().mapToInt(XwCart::getCount).sum();
    }
}
